function f(a) {
	console.log(a)
}

// f1000 最多每 1000ms 将调用传递给 f 一次
let f1000 = throttle(f, 1000)

f1000(1) // 显示 1
f1000(2) // (节流，尚未到 1000ms)
f1000(3) // (节流，尚未到 1000ms)

function throttle(func, ms) {
	// func == f（外部的 f 函数）
	let isThrottled = false,
		savedArgs,
		savedThis

	function wrapper(...args) {
		// 2. 已进入节流状态，只保存参数，不在往下执行调用函数。
		if (isThrottled) {
			savedArgs = args
			savedThis = globalThis
			return
		}

		isThrottled = true

		func.apply(globalThis, args) // 1. 进入节流状态，默认调用一次函数，然后创建一个节流回调函数等待执行。

		setTimeout(() => {
			// 3. 外部所有调用结束，开始执行延时任务中的节流回调，并使用上面最后一次调用传入的参数值。
			isThrottled = false
			if (savedArgs) {
				wrapper.apply(savedThis, savedArgs)
				savedArgs = savedThis = null
			}
		}, ms)
	}

	return wrapper
}

// * 节流：默认先调用一次，然后在指定时间内无论你调用多少次（每次调用不会重新计时），都只会在指定时间到达后执行最后一次的调用。

// 应用场景：跟踪鼠标移动，...
